/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <devmon/driver_abi.h>
#include <dlfcn.h>
#include <gtest/gtest.h>
#include <test_utilities/test_base.h>

#include "../../../drivers/bus/i2c/i2c.h"
#include "../../../drivers/bus/i2c_mux/i2c_mux.h"
#include "../../../drivers/chip/pca9545/pca9545.h"
#include "../../../drivers/internal/hasdef.h"
#include "../../test_utils/root_object.h"

using namespace dev;
using namespace devmon;

namespace drivers {
namespace chip {
namespace pca9545_test {

class pca9545_test_service : public mc::engine::service {
public:
    pca9545_test_service(const std::string& name) : mc::engine::service(name) {
    }
};

class Pca9545AbiTest : public mc::test::TestWithEngine {
public:
    static void SetUpTestSuite() {
        TestWithEngine::SetUpTestSuite();
        m_test_service->init();
        m_test_service->start();

        // 创建根对象
        m_root_object = root_object::create_root_object(m_test_service.get());

        load_driver();
    }

    static void TearDownTestSuite() {
        m_test_service->stop();
        m_root_object.reset();

        if (m_driver_handle != nullptr) {
            dlclose(m_driver_handle);
            m_driver_handle = nullptr;
        }
        if (m_i2c_driver_handle != nullptr) {
            dlclose(m_i2c_driver_handle);
            m_i2c_driver_handle = nullptr;
        }
        if (m_i2c_mux_driver_handle != nullptr) {
            dlclose(m_i2c_mux_driver_handle);
            m_i2c_mux_driver_handle = nullptr;
        }
        TestWithEngine::TearDownTestSuite();
    }

    void SetUp() override {
        // 底层驱动打桩会自动管理内存，无需手动清理
    }

    void TearDown() override {
        // 底层驱动打桩会自动管理内存，无需手动清理
    }

    static void load_driver() {
        // 加载PCA9545驱动
        m_driver_handle = dlopen("./opt/bmc/drivers/libPca9545.so", RTLD_LAZY);
        if (m_driver_handle == nullptr) {
            MC_THROW(mc::system_exception, "Failed to load Pca9545 driver: ${error}",
                     ("error", dlerror()));
        }
        register_device_driver_func func = reinterpret_cast<register_device_driver_func>(
            dlsym(m_driver_handle, "register_device_driver"));
        MC_ASSERT_THROW(func, mc::bad_function_call_exception,
                        "Failed to get register_device_driver function: ${error}",
                        ("error", dlerror()));

        device_driver_t* devices       = nullptr;
        uint8_t          devices_count = 0;
        status_t         ret           = func(&devices, &devices_count);
        MC_ASSERT_THROW(ret == STATUS_OK, mc::bad_function_call_exception,
                        "Failed to get device driver manager: ${error}", ("error", ret));

        m_devices.clear();
        m_devices.reserve(devices_count);
        for (uint8_t i = 0; i < devices_count; i++) {
            auto device_driver = std::make_shared<device_driver_t>(devices[i]);
            m_devices.emplace(device_driver->device_name, device_driver);
        }

        // 加载I2C驱动
        m_i2c_driver_handle = dlopen("./opt/bmc/drivers/libI2c.so", RTLD_LAZY);
        if (m_i2c_driver_handle == nullptr) {
            MC_THROW(mc::system_exception, "Failed to load I2c driver: ${error}",
                     ("error", dlerror()));
        }
        register_device_driver_func i2c_func = reinterpret_cast<register_device_driver_func>(
            dlsym(m_i2c_driver_handle, "register_device_driver"));
        MC_ASSERT_THROW(i2c_func, mc::bad_function_call_exception,
                        "Failed to get I2c register_device_driver function: ${error}",
                        ("error", dlerror()));

        device_driver_t* i2c_devices       = nullptr;
        uint8_t          i2c_devices_count = 0;
        status_t         i2c_ret           = i2c_func(&i2c_devices, &i2c_devices_count);
        MC_ASSERT_THROW(i2c_ret == STATUS_OK, mc::bad_function_call_exception,
                        "Failed to get I2c device driver manager: ${error}", ("error", i2c_ret));

        m_i2c_devices.clear();
        m_i2c_devices.reserve(i2c_devices_count);
        for (uint8_t i = 0; i < i2c_devices_count; i++) {
            auto device_driver = std::make_shared<device_driver_t>(i2c_devices[i]);
            m_i2c_devices.emplace(device_driver->device_name, device_driver);
        }

        // 加载I2C MUX驱动
        m_i2c_mux_driver_handle = dlopen("./opt/bmc/drivers/libI2cMux.so", RTLD_LAZY);
        if (m_i2c_mux_driver_handle == nullptr) {
            MC_THROW(mc::system_exception, "Failed to load I2cMux driver: ${error}",
                     ("error", dlerror()));
        }
        register_device_driver_func i2c_mux_func = reinterpret_cast<register_device_driver_func>(
            dlsym(m_i2c_mux_driver_handle, "register_device_driver"));
        MC_ASSERT_THROW(i2c_mux_func, mc::bad_function_call_exception,
                        "Failed to get I2cMux register_device_driver function: ${error}",
                        ("error", dlerror()));

        device_driver_t* i2c_mux_devices       = nullptr;
        uint8_t          i2c_mux_devices_count = 0;
        status_t         i2c_mux_ret           = i2c_mux_func(&i2c_mux_devices, &i2c_mux_devices_count);
        MC_ASSERT_THROW(i2c_mux_ret == STATUS_OK, mc::bad_function_call_exception,
                        "Failed to get I2cMux device driver manager: ${error}", ("error", i2c_mux_ret));

        m_i2c_mux_devices.clear();
        m_i2c_mux_devices.reserve(i2c_mux_devices_count);
        for (uint8_t i = 0; i < i2c_mux_devices_count; i++) {
            auto device_driver = std::make_shared<device_driver_t>(i2c_mux_devices[i]);
            m_i2c_mux_devices.emplace(device_driver->device_name, device_driver);
        }
    }

    // 创建并初始化总线驱动
    std::shared_ptr<device_driver> create_bus_driver(const std::string& driver_name) {
        if (driver_name == "I2c") {
            auto it = m_i2c_devices.find("I2c");
            if (it != m_i2c_devices.end()) {
                return it->second;
            }
        } else if (driver_name == "I2cMux") {
            auto it = m_i2c_mux_devices.find("I2cMux");
            if (it != m_i2c_mux_devices.end()) {
                return it->second;
            }
        }
        return nullptr;
    }

    mc::dict create_test_connector(uint8_t system_id = 1, uint8_t position = 1, uint8_t slot = 1) {
        return mc::dict{{"SystemId", system_id}, {"Position", position}, {"Slot", slot}};
    }

    // 创建总线CSR对象
    mc::dict create_bus_csr_object(uint8_t bus_id, uint32_t bus_speed, uint8_t bus_mode,
                                   uint8_t bus_slave_addr, bool bus_use_smbus) {
        return mc::dict{{"Id", bus_id},
                        {"Speed", bus_speed},
                        {"Mode", bus_mode},
                        {"SlaveAddr", bus_slave_addr},
                        {"UseSmbus", bus_use_smbus}};
    }

    // 创建I2C MUX CSR对象
    mc::dict create_i2c_mux_csr_object(uint8_t channel_id) {
        return mc::dict{{"ChannelId", channel_id}};
    }

    // 创建芯片CSR对象
    mc::dict create_chip_csr_object(uint32_t address, uint8_t offset_width, uint8_t address_width,
                                    uint32_t write_timeout, uint32_t read_timeout,
                                    uint8_t rw_block_size, uint8_t write_interval,
                                    uint8_t read_interval, uint8_t write_retry, uint8_t read_retry,
                                    uint8_t channel_num) {
        return mc::dict{{"Address", address},
                        {"OffsetWidth", offset_width},
                        {"AddrWidth", address_width},
                        {"WriteTmout", write_timeout},
                        {"ReadTmout", read_timeout},
                        {"RwBlockSize", rw_block_size},
                        {"WriteInterval", write_interval},
                        {"ReadInterval", read_interval},
                        {"WriteRetryTimes", write_retry},
                        {"ReadRetryTimes", read_retry},
                        {"ChannelNum", channel_num}};
    }

    static mc::shared_ptr<pca9545_test_service>                              m_test_service;
    static std::unordered_map<std::string, std::shared_ptr<device_driver_t>> m_devices;
    static void*                                                             m_driver_handle;
    static void*                                                             m_i2c_driver_handle;
    static void*                                                             m_i2c_mux_driver_handle;
    static std::unordered_map<std::string, std::shared_ptr<device_driver_t>> m_i2c_devices;
    static std::unordered_map<std::string, std::shared_ptr<device_driver_t>> m_i2c_mux_devices;
    static root_object_ptr                                                   m_root_object;
};

mc::shared_ptr<pca9545_test_service> Pca9545AbiTest::m_test_service =
    mc::make_shared<pca9545_test_service>("bmc.kepler.test_pca9545");
std::unordered_map<std::string, std::shared_ptr<device_driver_t>> Pca9545AbiTest::m_devices;
void* Pca9545AbiTest::m_driver_handle     = nullptr;
void* Pca9545AbiTest::m_i2c_driver_handle = nullptr;
void* Pca9545AbiTest::m_i2c_mux_driver_handle = nullptr;
std::unordered_map<std::string, std::shared_ptr<device_driver_t>> Pca9545AbiTest::m_i2c_devices;
std::unordered_map<std::string, std::shared_ptr<device_driver_t>> Pca9545AbiTest::m_i2c_mux_devices;
root_object_ptr                                                   Pca9545AbiTest::m_root_object;

// ========================= 驱动注册功能测试 =========================

TEST_F(Pca9545AbiTest, register_device_driver_success) {
    EXPECT_EQ(m_devices.size(), 1);
    EXPECT_TRUE(m_devices.find("Pca9545") != m_devices.end());

    // 验证I2C驱动也正确加载
    EXPECT_EQ(m_i2c_devices.size(), 1);
    EXPECT_TRUE(m_i2c_devices.find("I2c") != m_i2c_devices.end());

    // 验证I2C MUX驱动也正确加载
    EXPECT_EQ(m_i2c_mux_devices.size(), 1);
    EXPECT_TRUE(m_i2c_mux_devices.find("I2cMux") != m_i2c_mux_devices.end());
}

TEST_F(Pca9545AbiTest, device_driver_structure_validation) {
    for (const auto& [device_name, device_driver] : m_devices) {
        EXPECT_FALSE(std::string(device_driver->device_name).empty());
        EXPECT_TRUE(device_driver->ctor != nullptr);
        EXPECT_TRUE(device_driver->init != nullptr);
    }
}

// ========================= PCA9545设备创建测试 =========================
TEST_F(Pca9545AbiTest, create_pca9545_success) {
    // 使用唯一object_name创建内部对象
    std::string object_name = "test_pca9545_device_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 0);
    csr_object["object_name"] = object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);

    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto device = device_driver->ctor(&m_test_service, object_name.c_str());
    ASSERT_TRUE(device != nullptr);
    
    // 设置父对象后再注册
    auto pca9545_obj = static_cast<dev::pca9545_object*>(device);
    pca9545_obj->set_parent(m_root_object.get());
    m_test_service->register_object(static_cast<mc::engine::object_impl*>(device));
}

TEST_F(Pca9545AbiTest, create_pca9545_null_service) {
    std::string object_name = "test_pca9545_null_service_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 0);
    csr_object["object_name"] = object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);

    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto device = device_driver->ctor(nullptr, object_name.c_str());
    EXPECT_EQ(device, nullptr);
}

TEST_F(Pca9545AbiTest, create_pca9545_null_name) {
    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto device = device_driver->ctor(&m_test_service, nullptr);
    EXPECT_EQ(device, nullptr);
}

// ========================= PCA9545设备初始化测试 =========================
TEST_F(Pca9545AbiTest, init_pca9545_success) {
    // 先创建前级i2c内部对象
    std::string i2c_object_name = "test_i2c_for_pca9545";
    mc::mutable_dict i2c_csr = create_bus_csr_object(0, 3400, 0, 0x70, false);
    i2c_csr["object_name"] = i2c_object_name;
    auto i2c_internal = dev::device_manager::get_instance().create_bus(i2c_object_name, "I2c", i2c_csr);
    ASSERT_TRUE(i2c_internal != nullptr);
    
    // 创建pca9545内部对象
    std::string pca9545_object_name = "test_pca9545_init_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 0);
    csr_object["object_name"] = pca9545_object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(pca9545_object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);

    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto device = device_driver->ctor(&m_test_service, pca9545_object_name.c_str());
    ASSERT_TRUE(device != nullptr);
    auto connector  = create_test_connector(1, 1, 1);
    status_t ret = device_driver->init(device, &csr_object, &connector);
    EXPECT_EQ(ret, STATUS_OK);
    
    // 设置父对象后再注册
    auto pca9545_obj = static_cast<dev::pca9545_object*>(device);
    pca9545_obj->set_parent(m_root_object.get());
    m_test_service->register_object(static_cast<mc::engine::object_impl*>(device));
}

TEST_F(Pca9545AbiTest, init_pca9545_null_params) {
    std::string object_name = "test_pca9545_null_params_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 0);
    csr_object["object_name"] = object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);
    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto device = device_driver->ctor(&m_test_service, object_name.c_str());
    ASSERT_TRUE(device != nullptr);
    status_t ret = device_driver->init(device, nullptr, nullptr);
    EXPECT_EQ(ret, STATUS_ERROR);
}

TEST_F(Pca9545AbiTest, init_pca9545_null_device) {
    std::string object_name = "test_pca9545_null_device_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 0);
    csr_object["object_name"] = object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);
    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto connector  = create_test_connector(1, 1, 1);
    status_t ret = device_driver->init(nullptr, &csr_object, &connector);
    EXPECT_EQ(ret, STATUS_ERROR);
}

// ========================= PCA9545属性验证测试 =========================
TEST_F(Pca9545AbiTest, pca9545_properties_validation) {
    // 先创建前级i2c内部对象
    std::string i2c_object_name = "test_i2c_properties";
    mc::mutable_dict i2c_csr = create_bus_csr_object(0, 3400, 0, 0x70, false);
    i2c_csr["object_name"] = i2c_object_name;
    auto i2c_internal = dev::device_manager::get_instance().create_bus(i2c_object_name, "I2c", i2c_csr);
    ASSERT_TRUE(i2c_internal != nullptr);

    // 创建pca9545内部对象
    std::string pca9545_object_name = "test_pca9545_properties_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 2, 1, 200, 150, 64, 5, 3, 4, 2, 1);
    csr_object["object_name"] = pca9545_object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(pca9545_object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);

    auto device_driver = m_devices["Pca9545"];
    ASSERT_TRUE(device_driver != nullptr);
    auto device = device_driver->ctor(&m_test_service, pca9545_object_name.c_str());
    ASSERT_TRUE(device != nullptr);
    auto connector = create_test_connector(1, 1, 1);
    status_t init_ret = device_driver->init(device, &csr_object, &connector);
    ASSERT_EQ(init_ret, STATUS_OK);

    // 设置父对象后再注册
    auto pca9545_obj = static_cast<dev::pca9545_object*>(device);
    pca9545_obj->set_parent(m_root_object.get());
    m_test_service->register_object(static_cast<mc::engine::object_impl*>(device));

    // 验证interface_chip属性值
    EXPECT_EQ(pca9545_obj->m_interface_chip.Address.get_value(), 0x70);
    EXPECT_EQ(pca9545_obj->m_interface_chip.OffsetWidth.get_value(), 2);
    EXPECT_EQ(pca9545_obj->m_interface_chip.AddrWidth.get_value(), 1);
    EXPECT_EQ(pca9545_obj->m_interface_chip.WriteTmout.get_value(), 200);
    EXPECT_EQ(pca9545_obj->m_interface_chip.ReadTmout.get_value(), 150);
    EXPECT_EQ(pca9545_obj->m_interface_chip.RwBlockSize.get_value(), 64);
    EXPECT_EQ(pca9545_obj->m_interface_chip.WriteInterval.get_value(), 5);
    EXPECT_EQ(pca9545_obj->m_interface_chip.ReadInterval.get_value(), 3);
    EXPECT_EQ(pca9545_obj->m_interface_chip.WriteRetryTimes.get_value(), 4);
    EXPECT_EQ(pca9545_obj->m_interface_chip.ReadRetryTimes.get_value(), 2);

    // 验证interface_pca9545特有属性值
    EXPECT_EQ(pca9545_obj->m_interface_pca9545.ChannelNum.get_value(), 1);
}

// ========================= PCA9545功能测试 =========================
TEST_F(Pca9545AbiTest, channel_selection) {
    // 先创建前级i2c内部对象
    std::string i2c_object_name = "test_i2c_channel";
    mc::mutable_dict i2c_csr = create_bus_csr_object(0, 3400, 0, 0x70, false);
    i2c_csr["object_name"] = i2c_object_name;
    auto i2c_internal = dev::device_manager::get_instance().create_bus(i2c_object_name, "I2c", i2c_csr);
    ASSERT_TRUE(i2c_internal != nullptr);

    // 创建pca9545内部对象
    std::string pca9545_object_name = "test_pca9545_channel_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 4);
    csr_object["object_name"] = pca9545_object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(pca9545_object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);

    auto pca9545_driver = m_devices["Pca9545"];
    ASSERT_TRUE(pca9545_driver != nullptr);
    auto pca9545_device = pca9545_driver->ctor(&m_test_service, pca9545_object_name.c_str());
    ASSERT_TRUE(pca9545_device != nullptr);
    auto pca9545_obj = static_cast<dev::pca9545_object*>(pca9545_device);

    auto i2c_driver = create_bus_driver("I2c");
    ASSERT_TRUE(i2c_driver != nullptr);
    auto i2c_device = i2c_driver->ctor(&m_test_service, i2c_object_name.c_str());
    ASSERT_TRUE(i2c_device != nullptr);
    auto i2c_obj = static_cast<dev::I2c_object*>(i2c_device);

    auto bus_connector = create_test_connector(1, 1, 1);
    auto chip_connector = create_test_connector(1, 1, 1);

    // 初始化I2C总线
    status_t ret = i2c_driver->init(i2c_device, &i2c_csr, &bus_connector);
    ASSERT_EQ(ret, STATUS_OK);

    // 初始化PCA9545芯片
    ret = pca9545_driver->init(pca9545_device, &csr_object, &chip_connector);
    ASSERT_EQ(ret, STATUS_OK);

    // 设置父对象
    i2c_obj->set_parent(m_root_object.get());
    pca9545_obj->set_parent(i2c_obj);

    // 注册对象到服务
    m_test_service->register_object(pca9545_obj);
    m_test_service->register_object(i2c_obj);

    // 设置连接关系
    pca9545_internal->set_left_bus(i2c_internal);
    pca9545_internal->set_host_bus(i2c_internal);

    // 测试通道选择功能
    uint32_t result = pca9545_internal->open_channel(i2c_internal);
    ASSERT_EQ(result, 0);
}

TEST_F(Pca9545AbiTest, block_read_write) {
    // 先创建前级i2c内部对象
    std::string i2c_object_name = "test_i2c_rw";
    mc::mutable_dict i2c_csr = create_bus_csr_object(0, 3400, 0, 0x70, false);
    i2c_csr["object_name"] = i2c_object_name;
    auto i2c_internal = dev::device_manager::get_instance().create_bus(i2c_object_name, "I2c", i2c_csr);
    ASSERT_TRUE(i2c_internal != nullptr);

    // 创建pca9545内部对象
    std::string pca9545_object_name = "test_pca9545_rw_obj";
    mc::mutable_dict csr_object = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 4);
    csr_object["object_name"] = pca9545_object_name;
    auto pca9545_internal = dev::device_manager::get_instance().create_chip(pca9545_object_name, "Pca9545", csr_object);
    ASSERT_TRUE(pca9545_internal != nullptr);

    auto pca9545_driver = m_devices["Pca9545"];
    ASSERT_TRUE(pca9545_driver != nullptr);
    auto pca9545_device = pca9545_driver->ctor(&m_test_service, pca9545_object_name.c_str());
    ASSERT_TRUE(pca9545_device != nullptr);
    auto pca9545_obj = static_cast<dev::pca9545_object*>(pca9545_device);

    auto i2c_driver = create_bus_driver("I2c");
    ASSERT_TRUE(i2c_driver != nullptr);
    auto i2c_device = i2c_driver->ctor(&m_test_service, i2c_object_name.c_str());
    ASSERT_TRUE(i2c_device != nullptr);
    auto i2c_obj = static_cast<dev::I2c_object*>(i2c_device);

    auto bus_connector = create_test_connector(1, 1, 1);
    auto chip_connector = create_test_connector(1, 1, 1);

    // 初始化I2C总线
    status_t ret = i2c_driver->init(i2c_device, &i2c_csr, &bus_connector);
    ASSERT_EQ(ret, STATUS_OK);

    // 初始化PCA9545芯片
    ret = pca9545_driver->init(pca9545_device, &csr_object, &chip_connector);
    ASSERT_EQ(ret, STATUS_OK);

    // 设置父对象
    i2c_obj->set_parent(m_root_object.get());
    pca9545_obj->set_parent(i2c_obj);

    // 注册对象到服务
    m_test_service->register_object(pca9545_obj);
    m_test_service->register_object(i2c_obj);

    // 设置连接关系
    pca9545_internal->set_left_bus(i2c_internal);
    pca9545_internal->set_host_bus(i2c_internal);

    // 测试块读写功能
    std::string write_data = "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C";
    std::vector<uint8_t> write_data_vec(write_data.begin(), write_data.end());

    // 通过资源树对象的BlockIOWrite方法进行块写入
    pca9545_obj->m_interface_chip.BlockIOWrite(0x10, write_data_vec);

    // 通过资源树对象的BlockIORead方法进行块读取
    std::vector<uint8_t> read_buffer = pca9545_obj->m_interface_chip.BlockIORead(0x10, write_data.length());
    std::string read_result_str(read_buffer.begin(), read_buffer.end());
    ASSERT_EQ(read_result_str, write_data);
}

TEST_F(Pca9545AbiTest, complex_i2c_pca9545_connection) {
    // 先创建前级i2c内部对象
    std::string      i2c_a_object_name = "test_i2c_a";
    mc::mutable_dict i2c_a_csr         = create_bus_csr_object(0, 3400, 0, 0x70, false);
    i2c_a_csr["object_name"]           = i2c_a_object_name;
    auto i2c_a_internal =
        dev::device_manager::get_instance().create_bus(i2c_a_object_name, "I2c", i2c_a_csr);
    ASSERT_TRUE(i2c_a_internal != nullptr);

    std::string      i2c_mux_object_name = "test_i2c_mux";
    mc::mutable_dict i2c_mux_csr         = create_i2c_mux_csr_object(1);
    i2c_mux_csr["object_name"]           = i2c_mux_object_name;
    auto i2c_mux_internal =
        dev::device_manager::get_instance().create_bus(i2c_mux_object_name, "I2cMux", i2c_mux_csr);
    ASSERT_TRUE(i2c_mux_internal != nullptr);

    // 创建两个PCA9545内部对象
    std::string      pca9545_a_object_name = "test_pca9545_a_obj";
    mc::mutable_dict csr_a = create_chip_csr_object(0x70, 1, 1, 100, 100, 32, 1, 1, 3, 3, 4);
    csr_a["object_name"]   = pca9545_a_object_name;
    auto pca9545_a_internal =
        dev::device_manager::get_instance().create_chip(pca9545_a_object_name, "Pca9545", csr_a);
    ASSERT_TRUE(pca9545_a_internal != nullptr);

    std::string      pca9545_b_object_name = "test_pca9545_b_obj";
    mc::mutable_dict csr_b = create_chip_csr_object(0x71, 1, 1, 100, 100, 32, 1, 1, 3, 3, 4);
    csr_b["object_name"]   = pca9545_b_object_name;
    auto pca9545_b_internal =
        dev::device_manager::get_instance().create_chip(pca9545_b_object_name, "Pca9545", csr_b);
    ASSERT_TRUE(pca9545_b_internal != nullptr);

    auto pca9545_driver = m_devices["Pca9545"];
    ASSERT_TRUE(pca9545_driver != nullptr);

    // 创建两个PCA9545资源树对象
    auto pca9545_a_device = pca9545_driver->ctor(&m_test_service, pca9545_a_object_name.c_str());
    auto pca9545_b_device = pca9545_driver->ctor(&m_test_service, pca9545_b_object_name.c_str());
    ASSERT_TRUE(pca9545_a_device != nullptr);
    ASSERT_TRUE(pca9545_b_device != nullptr);
    auto pca9545_a_obj = static_cast<dev::pca9545_object*>(pca9545_a_device);
    auto pca9545_b_obj = static_cast<dev::pca9545_object*>(pca9545_b_device);

    auto i2c_driver = create_bus_driver("I2c");
    ASSERT_TRUE(i2c_driver != nullptr);
    auto i2c_mux_driver = create_bus_driver("I2cMux");
    ASSERT_TRUE(i2c_mux_driver != nullptr);

    // 创建I2C和I2C MUX资源树对象
    auto i2c_a_device = i2c_driver->ctor(&m_test_service, i2c_a_object_name.c_str());
    auto i2c_mux_device = i2c_mux_driver->ctor(&m_test_service, i2c_mux_object_name.c_str());
    ASSERT_TRUE(i2c_a_device != nullptr);
    ASSERT_TRUE(i2c_mux_device != nullptr);
    auto i2c_a_obj = static_cast<dev::I2c_object*>(i2c_a_device);
    auto i2c_mux_obj = static_cast<dev::i2c_mux_object*>(i2c_mux_device);

    auto bus_connector  = create_test_connector(1, 1, 1);
    auto chip_connector = create_test_connector(1, 1, 1);

    // 初始化I2C总线和I2C MUX
    status_t ret = i2c_driver->init(i2c_a_device, &i2c_a_csr, &bus_connector);
    ASSERT_EQ(ret, STATUS_OK);
    ret = i2c_mux_driver->init(i2c_mux_device, &i2c_mux_csr, &bus_connector);
    ASSERT_EQ(ret, STATUS_OK);

    // 初始化PCA9545对象
    ret = pca9545_driver->init(pca9545_a_device, &csr_a, &chip_connector);
    ASSERT_EQ(ret, STATUS_OK);
    ret = pca9545_driver->init(pca9545_b_device, &csr_b, &chip_connector);
    ASSERT_EQ(ret, STATUS_OK);

    // 设置父对象
    i2c_a_obj->set_parent(m_root_object.get());
    pca9545_a_obj->set_parent(i2c_a_obj);
    i2c_mux_obj->set_parent(pca9545_a_obj);
    pca9545_b_obj->set_parent(i2c_mux_obj);

    // 注册对象到服务
    m_test_service->register_object(pca9545_a_obj);
    m_test_service->register_object(pca9545_b_obj);
    m_test_service->register_object(i2c_a_obj);
    m_test_service->register_object(i2c_mux_obj);

    // 设置连接关系
    pca9545_a_internal->set_left_bus(i2c_a_internal);
    pca9545_a_internal->set_host_bus(i2c_a_internal);
    pca9545_b_internal->set_left_bus(i2c_mux_internal);
    pca9545_b_internal->set_host_bus(i2c_a_internal);
    i2c_mux_internal->set_left_chip(pca9545_a_internal);
    pca9545_b_internal->set_left_chip(pca9545_a_internal);

    // 测试PCA9545 A的BlockIOWrite和BlockIORead功能
    std::string test_data_a = "\x01\x02\x03\x04\x05\x06\x07\x08";
    std::vector<uint8_t> write_data_a(test_data_a.begin(), test_data_a.end());

    // 通过资源树对象的BlockIOWrite方法进行块写入
    pca9545_a_obj->m_interface_chip.BlockIOWrite(0x10, write_data_a);

    // 通过资源树对象的BlockIORead方法进行块读取
    std::vector<uint8_t> read_buffer_a = pca9545_a_obj->m_interface_chip.BlockIORead(0x10, test_data_a.length());
    std::string read_data_a(read_buffer_a.begin(), read_buffer_a.end());
    ASSERT_EQ(read_data_a, test_data_a);

    // 测试PCA9545 B的BlockIOWrite和BlockIORead功能
    std::string test_data_b = "\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10";
    std::vector<uint8_t> write_data_b(test_data_b.begin(), test_data_b.end());

    // 通过资源树对象的BlockIOWrite方法进行块写入
    pca9545_b_obj->m_interface_chip.BlockIOWrite(0x20, write_data_b);

    // 通过资源树对象的BlockIORead方法进行块读取
    std::vector<uint8_t> read_buffer_b = pca9545_b_obj->m_interface_chip.BlockIORead(0x20, test_data_b.length());
    std::string read_data_b(read_buffer_b.begin(), read_buffer_b.end());
    ASSERT_EQ(read_data_b, test_data_b);

    // 测试不同offset的读写操作
    std::string test_data_c = "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A";
    std::vector<uint8_t> write_data_c(test_data_c.begin(), test_data_c.end());

    // 通过PCA9545 A写入到不同offset
    pca9545_a_obj->m_interface_chip.BlockIOWrite(0x30, write_data_c);

    // 通过PCA9545 A从不同offset读取
    std::vector<uint8_t> read_buffer_c = pca9545_a_obj->m_interface_chip.BlockIORead(0x30, test_data_c.length());
    std::string read_data_c(read_buffer_c.begin(), read_buffer_c.end());
    ASSERT_EQ(read_data_c, test_data_c);
}

} // namespace pca9545_test
} // namespace chip
} // namespace drivers
